Advertisement
Guest User

Untitled

a guest
Aug 31st, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.11 KB | None | 0 0
  1. //#include <avr/pgmspace.h>
  2. #include <avr/interrupt.h>
  3. #include <util/atomic.h>
  4. #include <util/delay.h>
  5. #include <avr/wdt.h>
  6. #include <avr/io.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "io.h"
  11. #include "uart.h"
  12. #include "task.h"
  13. #include "1wire.h"
  14. #include "ds18b20.h"
  15.  
  16.  
  17. #define FAN   B,1
  18. #define LED_R B,2
  19. #define LED_G B,3
  20. #define LED_B B,4
  21. #define LED_W B,5
  22. #define DS_IN C,1
  23.  
  24. //#define streq(a,b) (strncmp(a,b,sizeof(b)-1)==0)
  25. #define streq(a,b) (strncmp(a,b,strlen(b))==0)
  26.  
  27. #define F_PWM 100
  28. #define PWM_STEPS 255
  29. #define PWM_PORT PORTB
  30.  
  31. static volatile uint8_t pwm_setting[4];
  32. static volatile uint8_t ready_to_get_temp=0;
  33.  
  34. ISR(TIMER2_OVF_vect) {
  35.   static uint8_t pwm_cnt=0;
  36.   uint8_t tmp=0;
  37.  
  38.   if (pwm_setting[0] > pwm_cnt) tmp |= (1<<2); //R
  39.   if (pwm_setting[1] > pwm_cnt) tmp |= (1<<3); //G
  40.   if (pwm_setting[2] > pwm_cnt) tmp |= (1<<4); //B
  41.   if (pwm_setting[3] > pwm_cnt) tmp |= (1<<5); //W
  42.  
  43.   PWM_PORT = tmp;
  44.     if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
  45.     pwm_cnt=0;
  46.   else
  47.     pwm_cnt++;
  48. }
  49.  
  50. uint8_t atoia(char *src, uint8_t *dst, int len){
  51.   // This function convert char array with digits into ints array.
  52.   // In addition return amount of digits that was able to find in *src.
  53.   // If more digits is in *src then max size of *dst, then zero is returned and
  54.   // *dst is zeroed.
  55.   uint8_t k=0;
  56.   uint8_t x=0;
  57.   dst[x] = 0;
  58.   while(*src++){
  59.     if (*src >= '0' && *src <= '9'){
  60.       if (x > len-1){
  61.         memset(dst, 0, len*sizeof(uint8_t));
  62.         return 0;
  63.       }
  64.       dst[x] = dst[x]*10 + *src - '0';
  65.       k = 1;
  66.     } else if (k>0){
  67.       x++;
  68.       dst[x] = 0;
  69.       k = 0;
  70.     }
  71.   }
  72.   return x;
  73. }
  74.  
  75. void rainbow_step(void) {
  76.   //Fade from blue to red
  77.   if(pwm_setting[2] > 0x00 && pwm_setting[0] == 0xFF && pwm_setting[1] == 0x00) {
  78.     pwm_setting[2]--;
  79.   }
  80.   if(pwm_setting[2] == 0xFF && pwm_setting[0] < 0xFF && pwm_setting[1] == 0x00) {
  81.     pwm_setting[0]++;
  82.   }
  83.  
  84.   //Fade from green to blue
  85.   if(pwm_setting[1] > 0x00 && pwm_setting[2] == 0xFF && pwm_setting[0] == 0x00) {
  86.     pwm_setting[1]--;
  87.   }
  88.   if(pwm_setting[1] == 0xFF && pwm_setting[2] < 0xFF && pwm_setting[0] == 0x00) {
  89.     pwm_setting[2]++;
  90.   }
  91.  
  92.   // Fade from red to green
  93.   if(pwm_setting[0] > 0x00 && pwm_setting[1] == 0xFF && pwm_setting[2] == 0x00) {
  94.     pwm_setting[0]--;
  95.   }
  96.   if(pwm_setting[0] == 0xFF && pwm_setting[1] < 0xFF && pwm_setting[2] == 0x00) {
  97.     pwm_setting[1]++;
  98.   }
  99. }
  100.  
  101. // 22ms timer
  102. void timer0_init(void){
  103.   TCCR0 = (1 << CS00)|(1 << CS02);  // Prescaler 1024
  104.   TIMSK |= (1 << TOIE0); // Enable timer for TIMER0_OVF_vect mode.
  105. }
  106.  
  107. void rgbw_pwm_init(uint8_t r, uint8_t g, uint8_t b, uint8_t w){
  108.  
  109.   pwm_setting[0] = r;
  110.   pwm_setting[1] = g;
  111.   pwm_setting[2] = b;
  112.   pwm_setting[3] = w;  
  113.  
  114.   TCCR2 |= (1 << WGM21)|(1 << WGM20)|(1 << CS20);
  115.   TIMSK |= (1 << TOIE2);
  116. }
  117.  
  118. // https://www.forbot.pl/forum/topics33/pwm-tryby-pracy-timera1-w-atmega-8-vt4640.htm
  119. // http://www.societyofrobots.com/member_tutorials/files/ATMega8.pdf
  120. // it`s timer_1
  121. void fan_pwm_init(void){
  122.   // 16 bit Fast PWM
  123.   TCCR1A |= (1<<WGM11);
  124.   //TCCR1B |= (1<<WGM12);// Comment out to have Phase correct instead Fast PWM
  125.   TCCR1B |= (1<<WGM13);
  126.   // Prescaler set to 1.
  127.   TCCR1B |= (1<<CS10);
  128.   // 12 MHz / (prescaler * (TOP + 1)) = 25 kHz
  129.   // 12000000/(1*(479+1)) == 25000Hz
  130.   // Set frequency to 25KHz.
  131.   ICR1 = 479;
  132.   // Set duty cycles.
  133.   //OCR1A = 448;
  134.   OCR1A = 428;
  135.   // Enable output on OC1A
  136.   TCCR1A |= (1<<COM1A1);
  137. }
  138.  
  139. void check_temp(void){
  140.   static int16_t dst=0;
  141.  
  142.   ds18b20_request_measure();
  143.   int16_t temp = ds18b20_get_temperature(ds_devices[0]);
  144.  
  145.   if (temp == 2000) return;
  146.   temp /= 10;
  147.   if (dst != temp){
  148.     dst = temp;
  149.     printf("ORG temp %d -> %d\n", temp, (ICR1-(temp-30)*6));
  150.  
  151.     temp = ICR1-(temp-30)*6;
  152.  
  153.     if (temp > ICR1) temp=ICR1;
  154.  
  155.     OCR1A = temp;
  156.     printf("OCR1A IS: %d and temp %d\n", temp, dst);
  157.   }
  158. }
  159.  
  160. // timer ~22ms
  161. ISR(TIMER0_OVF_vect){
  162.   static volatile uint8_t overflows=0;
  163.   if (overflows++ > 200){
  164.     overflows = 0;
  165.     ready_to_get_temp=1;
  166.   }
  167.  
  168. }
  169.  
  170. void delay_ms(uint8_t ms){
  171.   while(--ms){
  172.     _delay_ms(1);
  173.   }
  174. }
  175.  
  176. int __attribute__((noreturn)) main(void){
  177.   PRINTF_TO_UART;
  178.   uint8_t rainbow_on = 1;
  179.   uint16_t rainbow_speed = 5;
  180.   uint16_t fan_speed = 2;
  181.  
  182.   GPIO_OUTPUT(LED_R);
  183.   GPIO_OUTPUT(LED_G);
  184.   GPIO_OUTPUT(LED_B);
  185.   GPIO_OUTPUT(LED_W);
  186.   GPIO_OUTPUT(FAN);
  187.  
  188.   uart_init();
  189.   timer0_init();
  190.   rgbw_pwm_init(0xFF, 0, 0, 0);
  191.   fan_pwm_init();
  192.  
  193.   ds18b20_init(DS18B20_RESOLUTION_9_BITS);
  194.   wdt_enable(WDTO_2S);
  195.   sei();
  196.  
  197.   while(1){
  198.     wdt_reset();
  199.  
  200.     char *uart_rx_ptr = get_uart_rx();
  201.  
  202.     if (uart_rx_ptr != NULL){
  203.  
  204.       if (streq(uart_rx_ptr, "avr ping")){
  205.         printf("avr-pong\r\n");
  206.       } else if (streq(uart_rx_ptr, "avr rgbw")){
  207.         //atoia(uart_rx_ptr, (uint8_t *)pwm_setting, 4);
  208.         uint8_t i = atoia(uart_rx_ptr, (uint8_t *)pwm_setting, 4);
  209.         if (i==4){
  210.           printf("R: %d, G: %d, B: %d, W:%d\n", pwm_setting[0],pwm_setting[1],pwm_setting[2],pwm_setting[3]);
  211.         }
  212.       } else if (streq(uart_rx_ptr, "avr rainbow on")){
  213.         printf("avr rainbow on accepted.\n");
  214.         rainbow_on = 1;
  215.       } else if (streq(uart_rx_ptr, "avr rainbow off")){
  216.         printf("avr rainbow off accepted.\n");
  217.         rainbow_on = 0;
  218.       } else if (streq(uart_rx_ptr, "avr rainbow speed ")){
  219.         rainbow_speed = atoi(uart_rx_ptr+18);
  220.         printf("RS:%d WT\n", rainbow_speed);
  221.       } else if (streq(uart_rx_ptr, "avr fan speed ")){
  222.         fan_speed = (uint16_t)atoi(uart_rx_ptr+14);
  223.         if (fan_speed >= 0 && fan_speed <= ICR1){
  224.           OCR1A = fan_speed;
  225.           printf("FAN speed set to: %d\n", fan_speed);
  226.         } else {
  227.           printf("FAN speed incorrect: %d\n", fan_speed);
  228.         }
  229.       }
  230.       memset(uart_rx_ptr, 0, 250);
  231.     }
  232.  
  233.     if (rainbow_on == 1){
  234.         delay_ms(rainbow_speed);
  235.         rainbow_step();
  236.       //
  237.     }
  238.  
  239.     if (ready_to_get_temp == 1){
  240.       ready_to_get_temp = 0;
  241. //      ATOMIC_BLOCK(ATOMIC_FORCEON){
  242.         check_temp();
  243.       //}
  244.     }
  245.   }
  246.  
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement